package t10086.WorkThread;

import allrobots.sendMessages.ChangeStatus.ChangeRobot;
import t10086.Data.Broadcast;
import t10086.Data.Pop.PopType;
import t10086.WorkThread.Shared.Client.Client;
import t10086.Data.Pop.PopMsg;
import t10086.Data.Robot.RobotInfo;
import t10086.Data.Robot.RobotStatus;
import t10086.Data.Robot.RobotType;
import t10086.Model.Messages.Message;
import t10086.Model.Messages.MessageType;
import t10086.WorkThread.Shared.DataBuffer;
import t10086.WorkThread.Shared.ClientMap;

import allrobots.sendMessages.Register.Registration;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

public class MsgProcessHandler implements Runnable {
    private static final  BlockingQueue<Message> queue = new LinkedBlockingQueue<>();
    public static void putMessage(Message message)  {
        try {
            queue.put(message);
        } catch (InterruptedException e) {
            System.out.println("BroadcastUpdater put interrupted");
        }
    }
    @Override
    public void run() {
          while (!Thread.interrupted()) {
              try {
                  Message msg = queue.take();
        //          System.out.println("Message HANDLING: " + msg);
                  switch (msg.getType()) {
                      case REGISTER->{
//                          System.out.println("1");
                          //连接管理
//                          System.out.println("1");
                          System.out.println(msg.getNext());
                          Client client = ClientMap.getClient(msg.getNext());//辅助docker获取本地连接
//                          System.out.println("2");
                          Registration registration = msg.convertData(Registration.class);
//                          System.out.println("3");
                          client.setRole(registration.getRole());
//                          System.out.println("4");
                          client.setSerialNumber(registration.getSerialNumber());
//                          System.out.println("5");
                          ClientMap.putAddress(registration.getSerialNumber(),msg.getNext());
//                          System.out.println("2");
                          //信息管理
                          RobotInfo robotInfo = new RobotInfo();
                          robotInfo.setPosition(registration.getPosition());
                          robotInfo.setNext(registration.getPosition());
                          robotInfo.setTermination(registration.getPosition());
                          robotInfo.setListenedAddress(registration.getListenedSocket());
                          robotInfo.setSerialNumber(registration.getSerialNumber());
                          robotInfo.setWindow(0);
                          robotInfo.setSelfQueuingNumber(0);
                          robotInfo.setSelfMovingNumber(0);
                          robotInfo.setRobotStatus(RobotStatus.FREE);
//                          System.out.println("3");
                          if(DataBuffer.getBroadcast().getRobotInfoMap().get(registration.getSerialNumber()) != null) {
                              System.out.println("["+registration.getSerialNumber()+"::"+
                                      registration.getRole()+"] already registered!");
                          }
                          else if(registration.getRole()== RobotType.ROBOT){
                             if(DataBuffer.getBroadcast().putAndAddInfo(registration.getSerialNumber(), robotInfo))
                             {
                                 PopMsg popMsg = new PopMsg(
                                         PopType.REGISTER,
                                         RobotType.ROBOT,
                                         registration.getSerialNumber(),
                                         "REGISTERED!"
                                 );
                                 DataBuffer.getBroadcast().addPopMsg(popMsg);
                                 System.out.println("robot["+registration.getSerialNumber()+"]registered!");
                             }else{
                                 PopMsg popMsg = new PopMsg(
                                         PopType.REGISTER,
                                         RobotType.DELIVER,
                                         registration.getSerialNumber(),
                                         "REGISTERED!"
                                 );
                                 DataBuffer.getBroadcast().addPopMsg(popMsg);
                                 System.out.println("robot["+registration.getSerialNumber()+"]register failed!");
                             }
                          }else if(registration.getRole()==RobotType.DELIVER){
                              DataBuffer.getBroadcast().putRobotInfo(registration.getSerialNumber(), robotInfo);
                              System.out.println("deliver["+registration.getSerialNumber()+"]registered!");
                          }else {
                              System.out.println("REGISTER ERROR"+msg);
                          }

                      }
                      case ROBOT_UPLOAD->{
//                          System.out.println("1");
                          RobotInfo robotInfo = msg.convertData(RobotInfo.class);
//                          System.out.println("2");
                          DataBuffer.getBroadcast().updateRobotInfo(robotInfo);
//                          System.out.println("3");

//
//                          System.out.print(robotInfo.getSerialNumber()+":");
//                          System.out.print(robotInfo.getSelfMovingNumber());
//                          System.out.print(",");
//                          System.out.print(DataBuffer.getBroadcast().getMovingNumber());
//                          System.out.println();
                      }
                      case  STATUS_EXCHANGE->{
                          Map<String,Object> data = new HashMap<>();
                          data.put("messageId",msg.getMessageId());
                          Message restMsg= new Message(msg.getReceiver(),msg.getNext(),MessageType.RESPONSE,data);
                          ChangeRobot changeRobot = msg.convertData(ChangeRobot.class);
                          switch (changeRobot.getCurrentStatus()){
                              case FREE -> {
                                  if (changeRobot.getNextStatus()== RobotStatus.MOVING){
                                      long number = DataBuffer.getBroadcast().FreeToMoving(changeRobot.getSerialNumber());
                                      data.put("number",number);
                                  }else {
                                      String error ="ROBOT_UPLOAD ERROR: UNRECOGNIZED CHANGE MOD!";
                                      data.put("error",error);
                                      System.out.println(error+msg);
                                  }
                              }
                              case MOVING -> {
                                   if(changeRobot.getNextStatus()== RobotStatus.FREE){
                                      DataBuffer.getBroadcast().MovingToFree(changeRobot.getSerialNumber());
                                   }else  if(changeRobot.getNextStatus()== RobotStatus.QUEUING){

                                     DataBuffer.getBroadcast().MovingToQueuing(changeRobot.getSerialNumber(),changeRobot.getWindowNumber());
                                   }else {
                                       String error ="ROBOT_UPLOAD ERROR: UNRECOGNIZED CHANGE MOD!";
                                       data.put("error",error);
                                       System.out.println(error+msg);
                                   }
                              }
                              case QUEUING -> {
                                  if (changeRobot.getNextStatus()== RobotStatus.MOVING){
                                      DataBuffer.getBroadcast().QueuingToMoving(changeRobot.getSerialNumber(),changeRobot.getWindowNumber());
                                  }else {
                                      String error ="ROBOT_UPLOAD ERROR: UNRECOGNIZED CHANGE MOD!";
                                      data.put("error",error);
                                      System.out.println(error+msg);
                                  }
                              }
                              default -> {
                                  String error = "ROBOT_UPLOAD ERROR: UNRECOGNIZED STATUS!";
                                  data.put("error",error);
                                  System.out.println(error+msg);
                              }
                          }

                          LinkedList<Message>handleQueue=new LinkedList<>();
                          handleQueue.add(restMsg);
                          ThreadPoolManager.submitTask(new MsgConvertHandler(handleQueue));

                      }
                      case REST_ROBOT_REQUEST->{
                          Map<String,Object> data = new HashMap<>();
                          data.put("messageId",msg.getMessageId());
                          data.put("robotList",DataBuffer.getBroadcast().getFreeRobotInfos());
                          //docker
                          Message restMsg= new Message(msg.getReceiver(),msg.getNext(),MessageType.RESPONSE,data);
                          LinkedList<Message>handleQueue=new LinkedList<>();
                          handleQueue.add(restMsg);
                          ThreadPoolManager.submitTask(new MsgConvertHandler(handleQueue));
                      }
                      default ->{
                          System.out.println("Unrecognized message type: " + msg);
                      }
                  }
              } catch (InterruptedException e) {
                  Thread.currentThread().interrupt();  // 重新设置中断标志
                  System.out.println("RequestHandler take Interrupted");
                  return;
              }

          }
   }

}
